package com.ccp.dev.form.controller;

import com.ccp.dev.core.basic.annotion.Action;
import com.ccp.dev.core.basic.consts.UrlConstants;
import com.ccp.dev.core.basic.internationalization.SysBaseController;
import com.ccp.dev.core.basic.model.SysAuditModelType;
import com.ccp.dev.core.basic.response.ResultData;
import com.ccp.dev.core.basic.util.ContextUtil;
import com.ccp.dev.core.poi.excel.util.ExcelUtil;
import com.ccp.dev.core.util.*;
import com.ccp.dev.core.util.log.SysAuditThreadLocalHolder;
import com.ccp.dev.form.consts.FormConstants;
import com.ccp.dev.form.model.*;
import com.ccp.dev.form.service.*;
import com.ccp.dev.system.consts.SecretUtil;
import com.ccp.dev.system.model.Dictionary;
import com.ccp.dev.system.model.SysUser;
import com.ccp.dev.system.service.DictionaryService;
import com.ccp.dev.system.service.SysUserService;
import com.ccp.dev.workflow.model.ActDefModel;
import com.ccp.dev.workflow.service.ActDefModelService;
import com.ccp.dev.workflow.service.FormHandlerService;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 业务数据模板控制器类
 *
 * @author zhaowj
 */
@Controller
@RequestMapping(UrlConstants.PROJECT_ROOT + UrlConstants.PROJECT_MODULE_FORM + "/dataTemplate")
@Action(ownermodel = SysAuditModelType.FORM_MANAGEMENT)
public class DataTemplateController extends SysBaseController {

    @Resource
    private DataTemplateService dataTemplateService;

    @Resource
    private FormFieldService formFieldService;

    @Resource
    private ActDefModelService actDefModelService;

    @Resource
    private FormTableService formTableService;

    @Resource
    private FormDefService formDefService;

    @Resource
    private FormHandlerService formHandlerService;

    @Resource
    private SysBusEventService sysBusEventService;

    @Resource
    private PrintTemplateService printTemplateService;

    @Resource
    private DictionaryService dictionaryService;

    @Resource
    private SysUserService sysUserService;

    /**
     * 跳转到在线表单预览页面
     *
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/preview")
    @Action(description = "在线表单预览页面跳转", exectype = "页面跳转日志")
    public String dataTemplatePreview(HttpServletRequest request, ModelMap modelMap) {
        String formKey = RequestUtil.getString(request, "formKey");
        modelMap.put("formKey", formKey);
        //设置查询条件为动态传入时候需要参数字符串
        Map<String, Object> params = RequestUtil.getQueryMap(request);
        StringBuilder paramBuilder = new StringBuilder();
        int count = 0;
        for (String key : params.keySet()) {
            String value = params.get(key).toString();
            count++;
            if (count == 1) {
                paramBuilder.append("?" + key + "=" + value);
            } else {
                paramBuilder.append("&" + key + "=" + value);
            }
        }
        modelMap.put("paramStr", paramBuilder.toString());
        return getAutoView();
    }

    /**
     * 跳转到在线表单明细页面
     *
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/detail")
    @Action(description = "在线表单明细页面跳转", exectype = "页面跳转日志")
    public String dataTemplateDetail(HttpServletRequest request, ModelMap modelMap) {
        String id = RequestUtil.getString(request, "id");
        String formKey = RequestUtil.getString(request, "alias");
        String needHeadAndBottom = RequestUtil.getString(request, "needHeadAndBottom");
        //在流程实例详情页面内嵌表单时不需要显示操作按钮
        String hideBtn = RequestUtil.getString(request, "hideBtn");
        modelMap.put("formKey", formKey);
        modelMap.put("id", id);
        modelMap.put("hideBtn", hideBtn);
        modelMap.put("needHeadAndBottom", needHeadAndBottom);
        return getAutoView();
    }


    /**
     * 跳转到在线表单新增页面
     *
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/addEdit")
    @Action(description = "在线表单新增页面跳转", exectype = "页面跳转日志")
    public String dataTemplateAdd(HttpServletRequest request, ModelMap modelMap) {
        String id = RequestUtil.getString(request, "id");
        String formKey = RequestUtil.getString(request, "formKey");
        String procDefId = RequestUtil.getString(request, "procDefId");
        String nodeId = RequestUtil.getString(request, "nodeId");
        //在流程审批页面内嵌表单时不需要显示操作按钮
        String hideBtn = RequestUtil.getString(request, "hideBtn");
        //页面是否需要头和尾
        String needHeadAndBottom = RequestUtil.getString(request, "needHeadAndBottom");
        //是否允许修改密级
        int enableEditPrivacy = RequestUtil.getInt(request, "enableEditPrivacy",1);
        //根据formKey查询table是否为版本控制
        Integer needVer = formDefService.getNeedVerByFormKey(formKey);
        modelMap.put("formKey", formKey);
        modelMap.put("procDefId", procDefId);
        modelMap.put("nodeId", nodeId);
        modelMap.put("hideBtn", hideBtn);
        modelMap.put("id", id);
        modelMap.put("needVer", needVer);
        modelMap.put("needHeadAndBottom", needHeadAndBottom);
        modelMap.put("enableEditPrivacy", enableEditPrivacy);

        return getAutoView();
    }

    /**
     * 跳转到在线表单导入页面
     *
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/import")
    @Action(description = "在线表单导入页面跳转", exectype = "页面跳转日志")
    public String dataTemplateImport(HttpServletRequest request, ModelMap modelMap) {
        String formKey = RequestUtil.getString(request, "formKey");
        modelMap.put("formKey", formKey);
        return getAutoView();
    }


    /**
     * 添加或更新业务数据模板
     *
     * @param request 请求
     * @return ResultData
     */
    @RequestMapping(UrlConstants.MODULE_FUNCTION_ADD_UPDATE)
    @ResponseBody
    @Action(description = "添加或更新业务数据模板", exectype = "添加或更新日志",
            detail = "添加或更新业务数据模板<#if success>成功<#else>失败</#if>")
    public ResultData save(HttpServletRequest request) {
        DataTemplate dataTemplate = dataTemplateService.getFormObject(request);
        try {
            //表单字段调整顺序 修改字段表的sn
            formFieldService.updateFieldSn(dataTemplate.getDisplayField(), dataTemplate.getTableId());
            FormTable formTable = formTableService.getByTableId(dataTemplate.getTableId(), FormField.FIELD_NORMAL);
            dataTemplate.setSource((formTable.getIsExternal() == FormTable.NOT_EXTERNAL) ? DataTemplate.SOURCE_CUSTOM_TABLE : DataTemplate.SOURCE_OTHER_TABLE);
            //在这个过程中进行了第一次模板解释，然后复制到templateHtml上
            dataTemplateService.saveDataTemplate(dataTemplate);
            SysAuditThreadLocalHolder.putParamerter("success", true);
        } catch (Exception e) {
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("save.failure");
        }
        return getResultDataSuccess("save.success");
    }

    /**
     * 获取业务数据模板
     *
     * @param request 请求
     * @return 业务数据模板数据
     */
    @RequestMapping(UrlConstants.MODULE_FUNCTION_GET)
    @ResponseBody
    @Action(description = "获取业务数据模板", exectype = "查询日志",
            detail = "获取业务数据模板<#if success>成功<#else>失败</#if>")
    public ResultData edit(HttpServletRequest request) {
        String tableId = RequestUtil.getString(request, "tableId");
        String formKey = RequestUtil.getString(request, "formKey");
        DataTemplate bpmDataTemplate;
        try {
            FormTable formTable = formTableService.getByTableId(tableId, FormField.FIELD_NORMAL);
            //加密的字段不能作为查询条件
            List<FormField> fields = formTable.getFieldList();
            List<FormField> noEncryptFields = new ArrayList<>();
            for (FormField field : fields) {
                if (field.getIsEncrypt().equals(FormField.ISENCRYPT_NOT)) {
                    noEncryptFields.add(field);
                }
            }
            formTable.setQueryFieldList(noEncryptFields);
            bpmDataTemplate = dataTemplateService.getByFormKey(formKey);
            if (BeanUtils.isNotEmpty(bpmDataTemplate)) {
                String defId = bpmDataTemplate.getDefId();
                if (BeanUtils.isNotIncZeroEmpty(defId)) {
                    //绑定的流程定义
                    ActDefModel actDefModel = actDefModelService.getOneById(defId);
                    if (BeanUtils.isNotEmpty(actDefModel)) {
                        bpmDataTemplate.setSubject(actDefModel.getName());
                    }
                }
                bpmDataTemplate.setSource((formTable.getIsExternal() == FormTable.NOT_EXTERNAL) ? DataTemplate.SOURCE_CUSTOM_TABLE : DataTemplate.SOURCE_OTHER_TABLE);
            }
            SysAuditThreadLocalHolder.putParamerter("success", true);
        } catch (Exception e) {
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("query.failure");
        }
        return getResultDataSuccess("query.success", bpmDataTemplate);
    }


    /**
     * 查询在线表单设置信息
     *
     * @param request 请求
     * @return ResultData
     */
    @RequestMapping("/dataList")
    @ResponseBody
    @Action(description = "查询在线表单设置信息", exectype = "查询日志",
            detail = "查询在线表单设置信息<#if success>成功<#else>失败</#if>")
    public ResultData dataList(HttpServletRequest request) {
        //取得当前页URL,如有参数则带参数
        String alias = RequestUtil.getString(request, "alias");
        String url = "dataList_" + alias;
        String toReplaceUrl = "getDisplay_" + alias;
        String html;
        try {
            String baseURL = request.getRequestURI().replace(url, toReplaceUrl);
            Map<String, Object> params = RequestUtil.getQueryMap(request);
            Map<String, Object> queryParams = RequestUtil.getQueryParams(request);
            //取得传入参数ID
            params.put("__baseURL", baseURL);
            params.put(DataTemplate.PARAMS_KEY_CTX, request.getContextPath());
            params.put("__tic", "bpmDataTemplate");
            //获取业务模板数据
            DataTemplate bpmDataTemplate = dataTemplateService.getByFormKey(alias);
            if (BeanUtils.isEmpty(bpmDataTemplate)) {
                return getResultDataError("dataTemplate.preview.failure");
            }
            html = dataTemplateService.getDisplay(alias, params, queryParams);
            SysAuditThreadLocalHolder.putParamerter("success", true);
        } catch (Exception e) {
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("query.failure");
        }
        return getResultDataSuccess("query.success", html);
    }

    /**
     * 查询在线表单列表数据
     *
     * @param request 请求
     * @return ResultData 数据列表
     */
    @RequestMapping("/queryDataList")
    @ResponseBody
    @Action(description = "查询在线表单列表数据", exectype = "查询日志",
            detail = "查询在线表单列表数据<#if success>成功<#else>失败</#if>")
    public ResultData queryDataList(HttpServletRequest request) {
        List<Map<String, Object>> dataList;
        DataTemplate bpmDataTemplate;
        int totalCount;
        String alias = RequestUtil.getString(request, "formKey");
        //取得当前页URL,如有参数则带参数
        String url = "dataList_" + alias;
        String toReplaceUrl = "getDisplay_" + alias;
        try {
            String baseURL = request.getRequestURI().replace(url, toReplaceUrl);
            Map<String, Object> params = RequestUtil.getQueryMap(request);
            String filterKey = RequestUtil.getString(request, DataTemplate.PARAMS_KEY_FILTERKEY);
            params.put("__baseURL", baseURL);
            params.put(DataTemplate.PARAMS_KEY_FILTERKEY, filterKey);
            //20200513 主表增加密级字段dataPrivacyLevel过滤条件
            List<Integer> list = new ArrayList<>();
            List<Dictionary> dicList = dictionaryService.getByNodeKey(FormConstants.DICTYPE_SJMJ);
            //取用户密级，根据用户密级过滤
            String userId = ContextUtil.getCurrentUserId();
            SysUser sysUser = sysUserService.getById(userId);
            int sec = SecretUtil.getUserDataSecretMap().get(sysUser.getPrivacyLevel());
            for(Dictionary dic :dicList){
                int itemVal = Integer.parseInt(dic.getItemValue());
                if(itemVal>sec){
                    continue;
                }
                list.add(itemVal);
            }
            params.put(FormConstants.DATA_PRIVACY_LEVEL,list);

            bpmDataTemplate = dataTemplateService.getDataList(alias, params);
            //将数据中的千分位和货币类型进行转换
            dataList = formHandlerService.queryByDataTemplate(bpmDataTemplate);
            totalCount = bpmDataTemplate.getPageBean().getTotalCount();
            SysAuditThreadLocalHolder.putParamerter("success", true);
        } catch (Exception e) {
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("query.failure");
        }
        return getResultDataSuccess("query.success", totalCount, dataList);
    }

    /**
     * 在线表单新增或编辑获取设置的数据
     *
     * @param request  request
     * @param modelMap ModelMap
     * @return ResultData
     */
    @RequestMapping("/editData")
    @ResponseBody
    @Action(description = "在线表单新增或编辑获取设置的数据", exectype = "查询日志",
            detail = "在线表单新增或编辑获取设置的数据<#if success>成功<#else>失败</#if>")
    public ResultData editData(HttpServletRequest request, ModelMap modelMap) {
        String pk = RequestUtil.getString(request, "id");
        String alias = RequestUtil.getString(request, "alias");
        String procDefId = RequestUtil.getString(request, "procDefId", "#dataTem");
        String nodeId = RequestUtil.getString(request, "nodeId");
        boolean hasPk = StringUtil.isNotEmpty(pk);
        String ctxPath = request.getContextPath();
        FormDef formDef;
        String tableId;
        String tableName;
        String pkField;
        SysBusEvent sysBusEvent;
        if (StringUtil.isNotEmpty(alias)) {
            try {
                //根据 formKey获取表单
                formDef = formDefService.getDefaultVersionByFormKey(alias);
                //获取表
                tableId = formDef.getTableId();
                //根据tableId 获取table对象
                FormTable bpmFormTable = formTableService.getOneById(tableId);
                //获取table名字
                tableName = bpmFormTable.getTableName();
                if (null == formDef.getTemplate()) {
                    return getResultDataError("dataTemplate.design.warn");
                }
                Map<String, Object> dataMap = formHandlerService.formObtainHtml(formDef, pk, procDefId, nodeId, ctxPath);
                pkField = bpmFormTable.getPkField();
                formDef.setHtml(dataMap.get("html").toString());
                sysBusEvent = sysBusEventService.getByFormKey(alias);
                FormTable formTable = formTableService.getByTableId(tableId, 0);
                modelMap.put("formDef", formDef);
                modelMap.put("id", pk);
                modelMap.put("pkField", pkField);
                modelMap.put("tableId", tableId);
                modelMap.put("alias", alias);
                modelMap.put("tableName", tableName);
                modelMap.put("sysBusEvent", sysBusEvent);
                modelMap.put("hasPk", hasPk);
                modelMap.put("mainFields", dataMap.get("mainFields"));
                modelMap.put("subFields", dataMap.get("subFields"));
                modelMap.put("permission", dataMap.get("permission"));
                modelMap.put("formTable", formTable);
                SysAuditThreadLocalHolder.putParamerter("success", true);
            } catch (Exception e) {
                e.printStackTrace();
                SysAuditThreadLocalHolder.putParamerter("success", false);
                return getResultDataError("operation.failure");
            }
        }
        return getResultDataSuccess("operation.success", modelMap);
    }

    /**
     * 编辑数据模板的模板
     *
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/editTemplate")
    @ResponseBody
    @Action(description = "编辑数据模板的模板", exectype = "查询日志",
            detail = "编辑数据模板的模板<#if success>成功<#else>失败</#if>")
    public ResultData editTemplate(HttpServletRequest request) {
        String formKey = RequestUtil.getString(request, "formKey");
        DataTemplate dataTemplate;
        try {
            dataTemplate = dataTemplateService.getByFormKey(formKey);
            SysAuditThreadLocalHolder.putParamerter("success", true);
        } catch (Exception e) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("query.failure");
        }
        return getResultDataSuccess("query.success", dataTemplate);
    }

    /**
     * 保存或更新业务数据模板
     *
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/saveTemplate")
    @ResponseBody
    @Action(description = "保存或更新业务数据模板", exectype = "添加或更新日志",
            detail = "保存或更新业务数据模板<#if success>成功<#else>失败</#if>")
    public ResultData saveTemplate(HttpServletRequest request) {
        String id = RequestUtil.getString(request, "id");
        String templateHtml = RequestUtil.getString(request, "templateHtml");
        try {
            String decodeHtml = URLDecoder.decode(templateHtml.replaceAll("%;", "%25;"), "utf-8");
            DataTemplate newDataTemplate = dataTemplateService.getOneById(id);
            newDataTemplate.setTemplateHtml(decodeHtml);
            dataTemplateService.updateDataTemplate(newDataTemplate);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("save.success");
        } catch (Exception e) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("save.failure");
        }
    }

    /**
     * 删除在线表单的数据
     *
     * @param request 请求
     * @return 删除结果
     */
    @RequestMapping("/deleteData")
    @ResponseBody
    @Action(description = "删除在线表单的数据", exectype = "删除日志",
            detail = "删除在线表单的数据<#if success>成功<#else>失败</#if>")
    public ResultData deleteData(HttpServletRequest request) {
        String pk = RequestUtil.getString(request, "id");
        String alias = RequestUtil.getString(request, "alias");
        try {
            dataTemplateService.deleteData(alias, pk);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("delete.success");
        } catch (Exception ex) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("delete.failure");
        }
    }

    /**
     * 批量删除在线表单的数据
     *
     * @param request 请求
     * @return 删除结果
     */
    @RequestMapping("/batchDeleteData")
    @ResponseBody
    @Action(description = "批量删除在线表单的数据", exectype = "删除日志",
            detail = "批量删除在线表单的数据<#if success>成功<#else>失败</#if>")
    public ResultData batchDeleteData(HttpServletRequest request) {
        String ids = RequestUtil.getString(request, "ids");
        String alias = RequestUtil.getString(request, "alias");
        try {
            dataTemplateService.batchDeleteData(alias, ids);
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("delete.success");
        } catch (Exception ex) {
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("delete.failure");
        }
    }


    /**
     * 明细数据
     *
     * @param request 请求
     * @return 明细数据
     */
    @RequestMapping("/detailData")
    @ResponseBody
    @Action(description = "查询在线表单明细数据", exectype = "查询日志",
            detail = "查询在线表单明细数据<#if success>成功<#else>失败</#if>")
    public ResultData detailData(HttpServletRequest request) {
        try {
            String pk = RequestUtil.getString(request, "id");
            String alias = RequestUtil.getString(request, "alias");

            Map<String, Object> retMap = dataTemplateService.getForm(alias, pk);
            // 流程结束后的打印模板
            List<PrintTemplate> printTemplateList = printTemplateService.getAllByFormKeyAndForm(alias);
            Map<String, Object> dataMap = new HashMap<>(4);
            dataMap.put("form", retMap.get("html").toString());
            dataMap.put("id", pk);
            dataMap.put("formKey", alias);
            dataMap.put("printTemplateList", printTemplateList);
            dataMap.put("mainFields", retMap.get("mainFields"));
            dataMap.put("subFields", retMap.get("subFields"));
            SysAuditThreadLocalHolder.putParamerter("success", true);
            return getResultDataSuccess("query.success", dataMap);
        } catch (Exception e) {
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("query.failure");
        }
    }

    /**
     * 导出数据
     *
     * @param request 请求
     */
    @RequestMapping("/exportData")
    @Action(description = "在线表单导出数据", exectype = "导出日志",
            detail = "在线表单导出数据<#if success>成功<#else>失败</#if>")
    public void exportData(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> params = RequestUtil.getQueryMap(request);
        String alias = RequestUtil.getString(request, "alias");
        String[] exportIds = RequestUtil.getStringAryByStr(request, "__exportIds__");
        int exportType = 0;
        if (exportIds != null && exportIds.length > 0) {
            exportType = 1;
        }
        String fileName = "DataTemplate_" + DateFormatUtil.getNowByString("yyyyMMddHHmmdd");
        try {
            HSSFWorkbook wb = dataTemplateService.export(alias, exportIds, exportType, params);
            ExcelUtil.downloadExcel(wb, fileName, response);
            SysAuditThreadLocalHolder.putParamerter("success", true);
        } catch (Exception ex) {
            ex.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
        }
    }

    /**
     * 导入数据保存
     *
     * @param request 请求
     * @return ResultData
     */
    @RequestMapping("/importSave")
    @ResponseBody
    @Action(description = "在线表单导入数据", exectype = "导入日志",
            detail = "在线表单导入数据<#if success>成功<#else>失败</#if>")
    public ResultData importSave(MultipartHttpServletRequest request) {
        String alias = RequestUtil.getString(request, "alias");
        String importType = RequestUtil.getString(request, "importType");
        MultipartFile file = request.getFile("importFile");
        try {
            if (null != file) {
                dataTemplateService.importFile(file.getInputStream(), alias, importType);
                SysAuditThreadLocalHolder.putParamerter("success", true);
            }
        } catch (Exception e) {
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("success", false);
            return getResultDataError("dataTemplate.import.failure");
        }
        return getResultDataSuccess("dataTemplate.import.success");
    }
}
